/*!
 * jQuery ViewSlider Plugin
 * Version 0.1 [2011-11-01]
 * Lisenced under the GPLv2 license
 * Examples and documentation at: http://code.google.com/p/jquery-viewslider-plugin/
 *
 * Copyright 2011, Marc Selman
 */
;(function($){  
	$.fn.viewslider = function(method) {
		if (methods[method]) {
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		}
		else if (typeof method === 'object' || ! method) {
			return methods.init.apply(this, arguments);
		}
		else {
			$.error('Method ' +  method + ' does not exist on jQuery.viewslider');
		}
	};
	$.viewslider = {
		version: '0.1',
		defaults: {
			drag: 15,
			vertical: false,
			attachStart: 'middle',
			attachEnd: 'middle'
		}
	};

	var methods = {
		init : function(options) {
			var options = $.extend({}, $.viewslider.defaults, options);

			return this.each(function() {
				var viewslider = $(this);
				var items = viewslider.children().wrap('<div class="viewslider-item"></div>').parent();
				var panel = viewslider.children().wrapAll('<div class="viewslider-panel"></div>').parent().first();

				// OPTIONAL
				if (options.height) {
					viewslider.css('height', options.height);
				}
				if (options.width) {
					viewslider.css('width', options.width);
				}
				// MANDATORY
				viewslider.css('position', 'relative');
				viewslider.css('overflow', 'hidden');
				panel.css('position', 'absolute');
				if (options.vertical == true) {
					items.css('display', 'block');
				}
				else {
					panel.css('white-space', 'nowrap');
					items.css('display', 'inline-block');
				}
				
				$(window).load(function() {
					var data = {};
					data.attachStart = options.attachStart;
					data.attachEnd = options.attachEnd;
					data.drag = options.drag <= 0 ? 1 : options.drag + 1;
					data.panel = panel;
					data.vertical = options.vertical;
					if (options.startItem) {
						data.startItem = options.startItem;
					}
					else {
						data.startItem = items.first();
					}
					if (options.endItem) {
						data.endItem = options.endItem;
					}
					else {
						data.endItem = items.last();
					}
					setData(viewslider, data);
					
					viewslider.unbind('.viewslider');
					viewslider.bind('mousemove.viewslider', function(e) {
						var data = $(this).data('viewslider');
						var offset = 0;
						
						if (data.vertical) {
							offset = (((e.pageY - data.minPos) * (data.diff - 0)) / (data.maxPos - data.minPos)) + 0;
						}
						else {
							offset = (((e.pageX - data.minPos) * (data.diff - 0)) / (data.maxPos - data.minPos)) + 0;
						}
						
						if (offset < 0) {
							offset = 0;
						}
						if (offset > data.diff) {
							offset = data.diff;
						}
						data.offset = offset;
					});

					var offsetPos = 0;
					setInterval(function() {
						if (data.offset >= 0) {
							offsetPos += (data.offset - offsetPos) / data.drag;
							if (data.vertical == true) {
								data.panel.css('top', -offsetPos + 'px');
							}
							else {
								data.panel.css('left', -offsetPos + 'px');
							}
						}
					}, 10);
				});
			});
		},
		update : function() {
			return this.each(function() {
				var viewslider = $(this);
				var data = $(this).data('viewslider');
				
				if (data.vertical == true) {
					data.panel.css('top', '0px');
				}
				else {
					data.panel.css('left', '0px');
				}
				
				setData(viewslider, data);
			});
		}
	};
	
	function setData(viewslider, data) {
		if (data.vertical == true) {
			data.diff = data.panel.outerHeight()
				- viewslider.outerHeight()
				+ parseInt(viewslider.css('border-top-width'))
				+ parseInt(viewslider.css('border-bottom-width'));
				
			if (data.attachStart == 'start') {
				data.minPos = data.startItem.offset().top;
			}
			else if (data.attachStart == 'middle') {
				data.minPos = data.startItem.offset().top + (data.startItem.outerHeight() / 2);
			}
			else if (data.attachStart == 'end') {
				data.minPos = data.startItem.offset().top + data.startItem.outerHeight();
			}
			else {
				data.minPos = data.startItem.offset().top + data.attachStart;
			}
			
			if (data.attachEnd == 'start') {
				data.maxPos = data.endItem.offset().top - data.diff;
			}
			else if (data.attachEnd == 'middle') {
				data.maxPos = data.endItem.offset().top + (data.endItem.outerHeight() / 2) - data.diff;
			}
			else if (data.attachEnd == 'end') {
				data.maxPos = data.endItem.offset().top + data.endItem.outerHeight() - data.diff;
			}
			else {
				data.maxPos = data.endItem.offset().top + data.endItem.outerHeight() - data.diff - data.attachEnd;
			}
		}
		else {
			data.diff = data.panel.outerWidth()
				- viewslider.outerWidth()
				+ parseInt(viewslider.css('border-left-width'))
				+ parseInt(viewslider.css('border-right-width'));

			if (data.attachStart == 'start') {
				data.minPos = data.startItem.offset().left;
			}
			else if (data.attachStart == 'middle') {
				data.minPos = data.startItem.offset().left + (data.startItem.outerWidth() / 2);
			}
			else if (data.attachStart == 'end') {
				data.minPos = data.startItem.offset().left + data.startItem.outerWidth();
			}
			else {
				data.minPos = data.startItem.offset().left + data.attachStart;
			}
			
			if (data.attachEnd == 'start') {
				data.maxPos = data.endItem.offset().left - data.diff;
			}
			else if (data.attachEnd == 'middle') {
				data.maxPos = data.endItem.offset().left + (data.endItem.outerWidth() / 2) - data.diff;
			}
			else if (data.attachEnd == 'end') {
				data.maxPos = data.endItem.offset().left + data.endItem.outerWidth() - data.diff;
			}
			else {
				data.maxPos = data.endItem.offset().left + data.endItem.outerWidth() - data.diff - data.attachEnd;
			}
		}
		viewslider.data('viewslider', data);
	};
})(jQuery);